package system

import (
	"gin-admin/common/dto/response"
	"gin-admin/core"
	"gin-admin/enumeration"
	"gin-admin/global"
	"gin-admin/model"
	"gin-admin/service/dto/request"
	serviceResponse "gin-admin/service/dto/response"
	"gin-admin/utils"

	"github.com/jinzhu/copier"
)

type RoleService struct{}

var RoleServiceApp = &RoleService{}

func (rs *RoleService) CreateRoleService(requestData request.CreateRoleRequest) *response.ServiceError {
	var role model.Role
	condition := core.BuildQueryCondition(map[string]interface{}{
		"code": requestData.Code,
		"name": requestData.Name,
	})
	exists, err := core.CheckDataExistsByCondition(global.GA_DB, condition, &role)
	if err != nil {
		return err
	}
	if exists {
		return response.WrapError(response.RoleExistsCode, response.GetStatusCode(response.RoleExistsCode).Message)
	}
	if err := utils.ModelToStruct(&role, &requestData); err != nil {
		return err
	}
	if err := core.GenericCreateWithModel(global.GA_DB, &role); err != nil {
		return err
	}
	return nil
}

func (rs *RoleService) DeleteRoleService(requestData request.RoleDetailRequest) *response.ServiceError {
	var role model.Role
	var message string
	_, err := core.GenericQueryById(global.GA_DB, requestData.ID, &role, func() *response.ServiceError {
		message = response.GetStatusCode(response.MenuNotFoundCode).Message
		return response.WrapError(response.MenuNotFoundCode, message)
	})
	message = response.GetStatusCode(response.FailedCode).Message
	if err != nil {
		return response.WrapError(response.FailedCode, message)
	}
	if err := core.GenericLogicalDelete(global.GA_DB, role); err != nil {
		return response.WrapError(response.FailedCode, message)
	}
	return nil
}

func (rs *RoleService) UpdateRoleService(requestData request.ModifyRoleRequest) *response.ServiceError {
	var role model.Role
	var message string
	_, err := core.GenericQueryById(global.GA_DB, requestData.ID, &role, func() *response.ServiceError {
		message = response.GetStatusCode(response.MenuNotFoundCode).Message
		return response.WrapError(response.MenuNotFoundCode, message)
	})
	message = response.GetStatusCode(response.FailedCode).Message
	if err != nil {
		return response.WrapError(response.FailedCode, message)
	}
	result := global.GA_DB.Model(&role).Omit("id").Updates(&requestData)
	if err := core.HandelError(result); err != nil {
		return response.WrapError(response.FailedCode, message)
	}
	return nil
}

func (rs *RoleService) GetRoleInfoService(requestData request.RoleDetailRequest) (*serviceResponse.RoleResponse, *response.ServiceError) {
	var role model.Role
	var message string
	serviceResponse := serviceResponse.RoleResponse{}
	_, err := core.GenericQueryById(global.GA_DB, requestData.ID, &role, func() *response.ServiceError {
		message = response.GetStatusCode(response.MenuNotFoundCode).Message
		return response.WrapError(response.MenuNotFoundCode, message)
	})
	message = response.GetStatusCode(response.FailedCode).Message
	if err != nil {
		return &serviceResponse, response.WrapError(response.FailedCode, message)
	}
	if err := copier.Copy(&serviceResponse, &role); err != nil {
		global.GA_LOGGER.Sugar().Errorw("copier.Copy调用失败", "error", err)
		return &serviceResponse, response.WrapError(response.FailedCode, message)
	}

	serviceResponse.StatusName = enumeration.CommonStatus(role.Status).StatusString()
	return &serviceResponse, nil
}

func (rs *RoleService) GetRoleListService(requestData request.RoleListRequest) (*response.PaginationResponse, int64, error) {
	var roles []model.Role
	roleListResponse := response.PaginationResponse{}
	page := requestData.Page
	if requestData.Page == 0 {
		page = 1
	}
	offset := (page - 1) * requestData.Size
	result := global.GA_DB.Limit(requestData.Size).Offset(offset).Find(&roles)
	if err := core.HandelError(result); err != nil {
		return &roleListResponse, response.FailedCode, err
	}

	var serviceResponse serviceResponse.RoleResponse
	for _, role := range roles {
		copier.Copy(&serviceResponse, &role)
		serviceResponse.StatusName = enumeration.CommonStatus(role.Status).StatusString()
		roleListResponse.List = append(roleListResponse.List, serviceResponse)
	}

	var total int64
	result = global.GA_DB.Model(&model.Role{}).Count(&total)

	if err := core.HandelError(result); err != nil {
		return &roleListResponse, response.FailedCode, err
	}

	roleListResponse.Page = page
	roleListResponse.Size = requestData.Size
	roleListResponse.Total = total

	return &roleListResponse, response.SuccessCode, nil
}
